From 9575c0e70fed4e93fb95ed741c07ae60f40b3e5e Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sat, 1 Nov 2003 16:19:54 +0000 Subject: [PATCH] bitkeeper revision 1.547 (3fa3dd2aH8eamu3ONvYovJgq8wBNbQ) Many files: Fixes to the DOM0 interface and domain building code. Ready for new save/restore dom0_ops. --- tools/internal/xi_build.c | 27 +++++----- tools/internal/xi_start.c | 2 +- tools/internal/xi_stop.c | 2 +- xen/arch/i386/Rules.mk | 4 +- xen/common/dom0_ops.c | 36 +++++++++++-- xen/common/domain.c | 60 ++++++--------------- xen/common/memory.c | 4 +- xen/common/schedule.c | 1 - xen/include/hypervisor-ifs/dom0_ops.h | 77 +++++++++++++++++++-------- xen/include/xeno/sched.h | 2 +- 10 files changed, 124 insertions(+), 91 deletions(-) diff --git a/tools/internal/xi_build.c b/tools/internal/xi_build.c index 429048ec94..81f8a94097 100644 --- a/tools/internal/xi_build.c +++ b/tools/internal/xi_build.c @@ -146,7 +146,8 @@ static int copy_to_domain_page(unsigned long dst_pfn, void *src_page) static int setup_guestos( int dom, int kernel_fd, int initrd_fd, unsigned long tot_pages, - unsigned long virt_load_addr, size_t ksize, dom_meminfo_t *meminfo) + unsigned long virt_load_addr, size_t ksize, + dom0_builddomain_t *builddomain) { l1_pgentry_t *vl1tab = NULL, *vl1e = NULL; l2_pgentry_t *vl2tab = NULL, *vl2e = NULL; @@ -158,7 +159,7 @@ static int setup_guestos( unsigned long num_pgt_updates = 0; unsigned long count, pt_start, i, j; - memset(meminfo, 0, sizeof(*meminfo)); + memset(builddomain, 0, sizeof(*builddomain)); if ( init_pfn_mapper() < 0 ) goto error_out; @@ -211,8 +212,8 @@ static int setup_guestos( } /* 'i' is 'ksize' rounded up to a page boundary. */ - meminfo->virt_mod_addr = virt_load_addr + i; - meminfo->virt_mod_len = isize; + builddomain->virt_mod_addr = virt_load_addr + i; + builddomain->virt_mod_len = isize; for ( j = 0; j < isize; j += PAGE_SIZE, i += PAGE_SIZE ) { @@ -245,7 +246,7 @@ static int setup_guestos( */ l2tab = page_array[alloc_index] << PAGE_SHIFT; alloc_index--; - meminfo->l2_pgt_addr = l2tab; + builddomain->l2_pgt_addr = l2tab; /* * Pin down l2tab addr as page dir page - causes hypervisor to provide @@ -307,7 +308,7 @@ static int setup_guestos( num_pgt_updates++; } - meminfo->virt_startinfo_addr = + builddomain->virt_startinfo_addr = virt_load_addr + ((alloc_index-1)<= 0 ) close(initrd_fd); close(kernel_fd); - launch_op.u.meminfo.domain = domain_id; - launch_op.u.meminfo.virt_load_addr = load_addr; - launch_op.u.meminfo.num_vifs = atoi(argv[3]); - launch_op.u.meminfo.cmd_line[0] = '\0'; + launch_op.u.builddomain.domain = domain_id; + launch_op.u.builddomain.virt_load_addr = load_addr; + launch_op.u.builddomain.num_vifs = atoi(argv[3]); + launch_op.u.builddomain.cmd_line[0] = '\0'; cmd_len = 0; for ( count = args_start; count < argc; count++ ) { @@ -416,8 +417,8 @@ int main(int argc, char **argv) ERROR("Size of image boot params too big!\n"); break; } - strcat(launch_op.u.meminfo.cmd_line, argv[count]); - strcat(launch_op.u.meminfo.cmd_line, " "); + strcat(launch_op.u.builddomain.cmd_line, argv[count]); + strcat(launch_op.u.builddomain.cmd_line, " "); cmd_len += strlen(argv[count] + 1); } diff --git a/tools/internal/xi_start.c b/tools/internal/xi_start.c index 23b95ea742..7f59be637f 100644 --- a/tools/internal/xi_start.c +++ b/tools/internal/xi_start.c @@ -10,7 +10,7 @@ static int start_domain(int id) dom0_op_t op; op.cmd = DOM0_STARTDOMAIN; - op.u.meminfo.domain = id; + op.u.startdomain.domain = id; err = do_dom0_op(&op); diff --git a/tools/internal/xi_stop.c b/tools/internal/xi_stop.c index 8e5677edca..59e912149b 100644 --- a/tools/internal/xi_stop.c +++ b/tools/internal/xi_stop.c @@ -10,7 +10,7 @@ static int stop_domain(int id) dom0_op_t op; op.cmd = DOM0_STOPDOMAIN; - op.u.meminfo.domain = id; + op.u.stopdomain.domain = id; err = do_dom0_op(&op); diff --git a/xen/arch/i386/Rules.mk b/xen/arch/i386/Rules.mk index e137a1abd3..9e3421f14c 100644 --- a/xen/arch/i386/Rules.mk +++ b/xen/arch/i386/Rules.mk @@ -7,9 +7,9 @@ LD := ld MONITOR_BASE := 0xFC500000 # Bootloader should load monitor to this real address LOAD_BASE := 0x00100000 -CFLAGS := -nostdinc -fno-builtin -O3 -Wall -DMONITOR_BASE=$(MONITOR_BASE) +#CFLAGS := -nostdinc -fno-builtin -O3 -Wall -DMONITOR_BASE=$(MONITOR_BASE) CFLAGS += -fomit-frame-pointer -I$(BASEDIR)/include -D__KERNEL__ -DNDEBUG -#CFLAGS += -fomit-frame-pointer -I$(BASEDIR)/include -D__KERNEL__ +CFLAGS += -fomit-frame-pointer -I$(BASEDIR)/include -D__KERNEL__ LDFLAGS := -T xeno.lds -N diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 145e1febbe..b74c2d985d 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -97,11 +97,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_BUILDDOMAIN: { - struct task_struct * p = find_domain_by_id(op.u.meminfo.domain); + struct task_struct * p = find_domain_by_id(op.u.builddomain.domain); ret = -EINVAL; if ( p != NULL ) { - if ( (ret = final_setup_guestos(p, &op.u.meminfo)) == 0 ) + if ( (ret = final_setup_guestos(p, &op.u.builddomain)) == 0 ) ret = p->domain; put_task_struct(p); } @@ -110,7 +110,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_STARTDOMAIN: { - struct task_struct * p = find_domain_by_id(op.u.meminfo.domain); + struct task_struct * p = find_domain_by_id(op.u.startdomain.domain); ret = -EINVAL; if ( p != NULL ) { @@ -127,7 +127,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_STOPDOMAIN: { - ret = stop_other_domain(op.u.meminfo.domain); + ret = stop_other_domain(op.u.stopdomain.domain); } break; @@ -268,12 +268,38 @@ long do_dom0_op(dom0_op_t *u_dom0_op) op.u.getdominfo.mcu_advance = p->mcu_advance; op.u.getdominfo.tot_pages = p->tot_pages; op.u.getdominfo.cpu_time = p->cpu_time; + memcpy(&op.u.getdominfo.ctxt, + &p->shared_info->execution_context, + sizeof(execution_context_t)); } read_unlock_irqrestore(&tasklist_lock, flags); copy_to_user(u_dom0_op, &op, sizeof(op)); - break; } + break; + + case DOM0_GETPAGEFRAMEINFO: + { + struct pfn_info *page = frame_table + op.u.getpageframeinfo.pfn; + + op.u.getpageframeinfo.domain = page->flags & PG_domain_mask; + op.u.getpageframeinfo.type = NONE; + if ( page->type_count & REFCNT_PIN_BIT ) + { + switch ( page->flags & PG_type_mask ) + { + case PGT_l1_page_table: + op.u.getpageframeinfo.type = L1TAB; + break; + case PGT_l2_page_table: + op.u.getpageframeinfo.type = L2TAB; + break; + } + } + + copy_to_user(u_dom0_op, &op, sizeof(op)); + } + break; case DOM0_IOPL: { diff --git a/xen/common/domain.c b/xen/common/domain.c index 4aada60c52..8fa6b8c1f8 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -343,9 +343,8 @@ void release_task(struct task_struct *p) * */ -int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo) +int final_setup_guestos(struct task_struct *p, dom0_builddomain_t *builddomain) { - l2_pgentry_t * l2tab; start_info_t * virt_startinfo_addr; unsigned long virt_stack_addr; unsigned long phys_l2tab; @@ -356,28 +355,18 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo) if ( (p->flags & PF_CONSTRUCTED) ) return -EINVAL; - /* High entries in page table must contain hypervisor - * mem mappings - set them up. - */ - phys_l2tab = meminfo->l2_pgt_addr; - l2tab = map_domain_mem(phys_l2tab); - memcpy(&l2tab[DOMAIN_ENTRIES_PER_L2_PAGETABLE], - &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE], - (ENTRIES_PER_L2_PAGETABLE - DOMAIN_ENTRIES_PER_L2_PAGETABLE) - * sizeof(l2_pgentry_t)); - l2tab[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] = - mk_l2_pgentry(__pa(p->mm.perdomain_pt) | __PAGE_HYPERVISOR); - l2tab[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] = - mk_l2_pgentry(phys_l2tab | __PAGE_HYPERVISOR); + /* NB. Page base must already be pinned! */ + phys_l2tab = builddomain->l2_pgt_addr; p->mm.pagetable = mk_pagetable(phys_l2tab); - unmap_domain_mem(l2tab); + get_page_type(&frame_table[phys_l2tab>>PAGE_SHIFT]); + get_page_tot(&frame_table[phys_l2tab>>PAGE_SHIFT]); /* set up the shared info structure */ update_dom_time(p->shared_info); p->shared_info->domain_time = 0; /* we pass start info struct to guest os as function parameter on stack */ - virt_startinfo_addr = (start_info_t *)meminfo->virt_startinfo_addr; + virt_startinfo_addr = (start_info_t *)builddomain->virt_startinfo_addr; virt_stack_addr = (unsigned long)virt_startinfo_addr; /* we need to populate start_info struct within the context of the @@ -390,19 +379,19 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo) memset(virt_startinfo_addr, 0, sizeof(*virt_startinfo_addr)); virt_startinfo_addr->nr_pages = p->tot_pages; virt_startinfo_addr->shared_info = virt_to_phys(p->shared_info); - virt_startinfo_addr->pt_base = meminfo->virt_load_addr + + virt_startinfo_addr->pt_base = builddomain->virt_load_addr + ((p->tot_pages - 1) << PAGE_SHIFT); /* module size and length */ - virt_startinfo_addr->mod_start = meminfo->virt_mod_addr; - virt_startinfo_addr->mod_len = meminfo->virt_mod_len; + virt_startinfo_addr->mod_start = builddomain->virt_mod_addr; + virt_startinfo_addr->mod_len = builddomain->virt_mod_len; virt_startinfo_addr->dom_id = p->domain; virt_startinfo_addr->flags = IS_PRIV(p) ? SIF_PRIVILEGED : 0; /* Add virtual network interfaces and point to them in startinfo. */ - while (meminfo->num_vifs-- > 0) { + while (builddomain->num_vifs-- > 0) { net_vif = create_net_vif(p->domain); shared_rings = net_vif->shared_rings; if (!shared_rings) panic("no network ring!\n"); @@ -421,7 +410,7 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo) virt_startinfo_addr->blk_ring = virt_to_phys(p->blk_ring_base); /* Copy the command line */ - strcpy(virt_startinfo_addr->cmd_line, meminfo->cmd_line); + strcpy(virt_startinfo_addr->cmd_line, builddomain->cmd_line); /* Reinstate the caller's page tables. */ __asm__ __volatile__ ( @@ -431,7 +420,7 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo) p->flags |= PF_CONSTRUCTED; new_thread(p, - (unsigned long)meminfo->virt_load_addr, + (unsigned long)builddomain->virt_load_addr, (unsigned long)virt_stack_addr, (unsigned long)virt_startinfo_addr); @@ -571,17 +560,6 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params, unmap_domain_mem(l1start); /* pages that are part of page tables must be read only */ - cur_address = list_entry(p->pg_head.next, struct pfn_info, list) - - frame_table; - cur_address <<= PAGE_SHIFT; - for ( count = 0; count < alloc_index; count++ ) - { - list_ent = frame_table[cur_address >> PAGE_SHIFT].list.next; - cur_address = list_entry(list_ent, struct pfn_info, list) - - frame_table; - cur_address <<= PAGE_SHIFT; - } - l2tab = l2start + l2_table_offset(virt_load_address + (alloc_index << PAGE_SHIFT)); l1start = l1tab = map_domain_mem(l2_pgentry_to_phys(*l2tab)); @@ -589,21 +567,17 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params, l2tab++; for ( count = alloc_index; count < p->tot_pages; count++ ) { - *l1tab++ = mk_l1_pgentry(l1_pgentry_val(*l1tab) & ~_PAGE_RW); + *l1tab = mk_l1_pgentry(l1_pgentry_val(*l1tab) & ~_PAGE_RW); + page = frame_table + l1_pgentry_to_pagenr(*l1tab); + page->flags = dom | PGT_l1_page_table; + page->tot_count++; + l1tab++; if( !((unsigned long)l1tab & (PAGE_SIZE - 1)) ) { unmap_domain_mem(l1start); l1start = l1tab = map_domain_mem(l2_pgentry_to_phys(*l2tab)); l2tab++; } - page = frame_table + (cur_address >> PAGE_SHIFT); - page->flags = dom | PGT_l1_page_table; - page->tot_count++; - - list_ent = frame_table[cur_address >> PAGE_SHIFT].list.next; - cur_address = list_entry(list_ent, struct pfn_info, list) - - frame_table; - cur_address <<= PAGE_SHIFT; } page->type_count |= REFCNT_PIN_BIT; page->tot_count |= REFCNT_PIN_BIT; diff --git a/xen/common/memory.c b/xen/common/memory.c index 78f0d4192f..1629118929 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -363,7 +363,7 @@ static int dec_page_refcnt(unsigned long page_nr, unsigned int type) type); return -1; } - ASSERT(page_type_count(page) != 0); + ASSERT((page_type_count(page) & ~REFCNT_PIN_BIT) != 0); put_page_tot(page); return put_page_type(page); } @@ -568,7 +568,7 @@ static void put_page(unsigned long page_nr, int writeable) page = frame_table + page_nr; ASSERT(DOMAIN_OKAY(page->flags)); ASSERT((!writeable) || - ((page_type_count(page) != 0) && + (((page_type_count(page) & ~REFCNT_PIN_BIT) != 0) && ((page->flags & PG_type_mask) == PGT_writeable_page) && ((page->flags & PG_need_flush) == PG_need_flush))); if ( writeable ) diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 9cd98b65a5..ee85abcf04 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -328,7 +328,6 @@ asmlinkage void __enter_scheduler(void) /* do some accounting */ ranfor = (s32)(now - prev->lastschd); - ASSERT((ranfor>0)); prev->cpu_time += ranfor; /* calculate mcu and update avt */ diff --git a/xen/include/hypervisor-ifs/dom0_ops.h b/xen/include/hypervisor-ifs/dom0_ops.h index c5c4f97298..6f1cd137b0 100644 --- a/xen/include/hypervisor-ifs/dom0_ops.h +++ b/xen/include/hypervisor-ifs/dom0_ops.h @@ -10,23 +10,13 @@ #ifndef __DOM0_OPS_H__ #define __DOM0_OPS_H__ -#define DOM0_GETMEMLIST 2 -#define DOM0_BVTCTL 6 -#define DOM0_ADJUSTDOM 7 -#define DOM0_CREATEDOMAIN 8 -#define DOM0_DESTROYDOMAIN 9 -#define DOM0_STARTDOMAIN 10 -#define DOM0_STOPDOMAIN 11 -#define DOM0_GETDOMAININFO 12 -#define DOM0_BUILDDOMAIN 13 -#define DOM0_IOPL 14 -#define DOM0_MSR 15 -#define DOM0_DEBUG 16 -#define DOM0_SETTIME 17 +#include "hypervisor-if.h" + #define MAX_CMD_LEN 256 #define MAX_DOMAIN_NAME 16 +#define DOM0_CREATEDOMAIN 8 typedef struct dom0_newdomain_st { /* IN parameters. */ @@ -36,12 +26,29 @@ typedef struct dom0_newdomain_st unsigned int domain; } dom0_newdomain_t; +#define DOM0_STARTDOMAIN 10 +typedef struct dom0_startdomain_st +{ + /* IN parameters. */ + unsigned int domain; +} dom0_startdomain_t; + +#define DOM0_STOPDOMAIN 11 +typedef struct dom0_stopdomain_st +{ + /* IN parameters. */ + unsigned int domain; +} dom0_stopdomain_t; + +#define DOM0_DESTROYDOMAIN 9 typedef struct dom0_killdomain_st { + /* IN variables. */ unsigned int domain; int force; } dom0_killdomain_t; +#define DOM0_GETMEMLIST 2 typedef struct dom0_getmemlist_st { /* IN variables. */ @@ -52,8 +59,10 @@ typedef struct dom0_getmemlist_st unsigned long num_pfns; } dom0_getmemlist_t; -typedef struct domain_launch +#define DOM0_BUILDDOMAIN 13 +typedef struct dom0_builddomain_st { + /* IN variables. */ unsigned int domain; unsigned long l2_pgt_addr; unsigned long virt_load_addr; @@ -62,22 +71,28 @@ typedef struct domain_launch char cmd_line[MAX_CMD_LEN]; unsigned long virt_mod_addr; unsigned long virt_mod_len; -} dom_meminfo_t; + execution_context_t ctxt; +} dom0_builddomain_t; +#define DOM0_BVTCTL 6 typedef struct dom0_bvtctl_st { - unsigned long ctx_allow; /* context switch allowance */ + /* IN variables. */ + unsigned long ctx_allow; /* context switch allowance */ } dom0_bvtctl_t; +#define DOM0_ADJUSTDOM 7 typedef struct dom0_adjustdom_st { - unsigned int domain; /* domain id */ - unsigned long mcu_adv; /* mcu advance: inverse of weight */ - unsigned long warp; /* time warp */ - unsigned long warpl; /* warp limit */ - unsigned long warpu; /* unwarp time requirement */ + /* IN variables. */ + unsigned int domain; /* domain id */ + unsigned long mcu_adv; /* mcu advance: inverse of weight */ + unsigned long warp; /* time warp */ + unsigned long warpl; /* warp limit */ + unsigned long warpu; /* unwarp time requirement */ } dom0_adjustdom_t; +#define DOM0_GETDOMAININFO 12 typedef struct dom0_getdominfo_st { /* IN variables. */ @@ -91,14 +106,27 @@ typedef struct dom0_getdominfo_st unsigned long mcu_advance; unsigned int tot_pages; long long cpu_time; + execution_context_t ctxt; } dom0_getdominfo_t; +#define DOM0_GETPAGEFRAMEINFO 18 +typedef struct dom0_getpageframeinfo_st +{ + /* IN variables. */ + unsigned long pfn; /* Machine page frame number to query. */ + /* OUT variables. */ + unsigned int domain; /* To which domain does the frame belong? */ + enum { NONE, L1TAB, L2TAB } type; /* Is the page PINNED to a type? */ +} dom0_getpageframeinfo_t; + +#define DOM0_IOPL 14 typedef struct dom0_iopl_st { unsigned int domain; unsigned int iopl; } dom0_iopl_t; +#define DOM0_MSR 15 typedef struct dom0_msr_st { /* IN variables. */ @@ -108,6 +136,7 @@ typedef struct dom0_msr_st unsigned int out1, out2; } dom0_msr_t; +#define DOM0_DEBUG 16 typedef struct dom0_debug_st { /* IN variables. */ @@ -121,6 +150,7 @@ typedef struct dom0_debug_st * Set clock such that it would read after 00:00:00 UTC, * 1 January, 1970 if the current system time was . */ +#define DOM0_SETTIME 17 typedef struct dom0_settime_st { /* IN variables. */ @@ -134,12 +164,15 @@ typedef struct dom0_op_st union { dom0_newdomain_t newdomain; + dom0_startdomain_t startdomain; + dom0_stopdomain_t stopdomain; dom0_killdomain_t killdomain; dom0_getmemlist_t getmemlist; dom0_bvtctl_t bvtctl; dom0_adjustdom_t adjustdom; - dom_meminfo_t meminfo; + dom0_builddomain_t builddomain; dom0_getdominfo_t getdominfo; + dom0_getpageframeinfo_t getpageframeinfo; dom0_iopl_t iopl; dom0_msr_t msr; dom0_debug_t debug; diff --git a/xen/include/xeno/sched.h b/xen/include/xeno/sched.h index b150072406..40c3e08d6e 100644 --- a/xen/include/xeno/sched.h +++ b/xen/include/xeno/sched.h @@ -223,7 +223,7 @@ extern int setup_guestos( struct task_struct *p, dom0_newdomain_t *params, unsigned int num_vifs, char *data_start, unsigned long data_len, char *cmdline, unsigned long initrd_len); -extern int final_setup_guestos(struct task_struct *p, dom_meminfo_t *); +extern int final_setup_guestos(struct task_struct *p, dom0_builddomain_t *); struct task_struct *find_domain_by_id(unsigned int dom); extern void release_task(struct task_struct *); -- 2.30.2